﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Model.Dto.YS;
using DFGK_WMS.Model.Models;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace DFGK.Service
{
    public class MaterialService : BaseService, IMaterialService
    {
        private readonly IMaterialCategoryRepository _materialCategoryRepository;
        private readonly IMaterialPackageRepository _materialPackageRepository;
        private readonly IMaterialGroupRepository _materialGroupRepository;
        private readonly IStockRepository stockRepository;
        private readonly IMaterialRepository _materialRepository;
        private readonly IDictItemRepository _itemRepository;
        private readonly IUnitOfWork _unitOfWork;
        public MaterialService(IMapper mapper, IMaterialCategoryRepository _materialCategoryRepository, IMaterialRepository _materialRepository, IMaterialGroupRepository _materialGroupRepository, IDictItemRepository _itemRepository, IUnitOfWork unitOfWork, IMaterialPackageRepository _materialPackageRepository, IStockRepository stockRepository) : base(mapper)
        {
            this._materialCategoryRepository = _materialCategoryRepository;
            this._materialPackageRepository = _materialPackageRepository;
            this._materialGroupRepository = _materialGroupRepository;
            this._materialRepository = _materialRepository;
            this._itemRepository = _itemRepository;
            _unitOfWork = unitOfWork;
            this.stockRepository = stockRepository;
        }

        public bool AddMaterial(Material m, out string message)
        {
            bool result = false;
            message = string.Empty;
            var obj = _materialRepository.QueryIsEntityWhere(x => x.Code == m.Code);
            if (obj != null)
            {
                message = "物料编码已存在！";
                return false;
            }
            if (m.UnitId == null)
            {
                message = "请选择计量单位！";
                return false;
            }
            var iobj = _itemRepository.QueryEntityById((long)m.UnitId);
            if(iobj == null)
            {
                message = "找不到该计量单位！";
                return false;
            }
            else
                m.UnitName = iobj.ItemName;

            if (m.MaterialCategoryId == null)
            {
                message = "请选择物料分类！";
                return false;
            }
            var mcobj = _materialCategoryRepository.QueryEntityById((long)m.MaterialCategoryId);
            if (mcobj == null)
            {
                message = "找不到该分类！";
                return false;
            }
            else
                m.MaterialCategoryName = mcobj.Name;

            _materialRepository.AddEntity(m);
            result = _unitOfWork.SaveChangesEntity();
            if (!result)
                return false;
            if (m.IsDismantle != null && m.IsDismantle == true)
            {
                if(m.SubPackageUnitId == null)
                {
                    message = "请选择子计量单位！";
                    return false;
                }
                var iobjs = _itemRepository.QueryEntityById((long)m.SubPackageUnitId);
                if (iobjs == null)
                {
                    message = "找不到该计量单位！";
                    return false;
                }
                else
                {
                    m.SubPackageUnitName = iobjs.ItemName;
                }
                MaterialPackage materialPackage = new MaterialPackage();
                materialPackage.MaterialId = m.Id;
                materialPackage.MaterialCode = m.Code;
                materialPackage.MaterialName = m.Name;
                materialPackage.ConversionFactor = m.ConversionFactor;
                materialPackage.PackageLevel = 1;
                materialPackage.PackageUnitId = iobj.Id;
                materialPackage.PackageUnitName = iobj.ItemName;
                materialPackage.SubPackageUnitId = m.SubPackageUnitId;
                materialPackage.SubPackageUnitName = m.SubPackageUnitName;
                _materialPackageRepository.AddEntity(materialPackage);
                return _unitOfWork.SaveChangesEntity();
            }
            return true;
        }

        public bool AddMaterialList(List<Material> list, out string message)
        {
            message = string.Empty;

            foreach (var item in list)
            {
                try
                {
                    // 生成唯一ID
                    item.Id = YitIdHelper.NextId();

                    // 检查Code是否重复
                    var existingMaterial = _materialRepository.QueryIsEntityWhere(x => x.Code == item.Code);
                    if (existingMaterial != null)
                    {
                        message = $"{item.Code}编码已存在";
                        return false;
                    }

                    // 添加单条记录
                    _materialRepository.AddEntity(item);

                    // 提交事务
                    var result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                    {
                        message = "提交失败，请重试";
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    message = $"添加失败：{ex.Message}";
                    // 记录异常日志
                    return false;
                }
            }

            return true;
        }
        public bool Addmateriallist(List<FengRenMaterialDataDTO> m)
        {
            // 查询数据库中所有已存在的材料代码
            var existingMaterials = _materialRepository.GetAllEntityList();
            var existingMaterialCodesSet = new HashSet<string>(existingMaterials.Select(m => m.Code));

            // 创建一个新的材料列表，只包含不存在的材料代码
            List<Material> materialList = new();

            // 在循环外收集需要更新的材料
            List<Material> materialsToUpdate = new();

            foreach (var item in m)
            {
                if (!existingMaterialCodesSet.Contains(item.Code))
                {
                    var material = new Material
                    {
                        Id = YitIdHelper.NextId(),
                        Code = item.Code,
                        Name = item.Name,
                        ModelSpec = item.ModelSpec,
                        UnitName = item.UnitName,
                        UnitGroup=item.UnitGroup,
                        IsBatchNoManage=item.IsBatchNoManage,
                        Coefficient=item.Coefficient,
                        CreateUserId = 0,
                        ModifyUserId = 0,
                        ModifyDate = DateTime.Now,
                        CreateDate = DateTime.Now,
                        IsDel = false
                    };
                    materialList.Add(material);
                }
                else
                {
                    // 材料代码已存在，更新现有材料
                    var existingMaterial = existingMaterials.FirstOrDefault(m => m.Code == item.Code);
                    if (existingMaterial != null)
                    {
                        existingMaterial.Name = item.Name; // 假设需要更新名称
                        existingMaterial.UnitName = item.UnitName; // 假设需要更新单位名称
                        
                        existingMaterial.ModifyDate = DateTime.Now; // 更新修改日期
                        materialsToUpdate.Add(existingMaterial);
                    }
                }
            }

            //执行批量修改的操作
            if (materialsToUpdate.Count > 0)
            {
                _materialRepository.UpdEntityList(materialsToUpdate);
            }

            // 执行批量插入操作
            _materialRepository.AddEntityList(materialList);

            // 保存更改
            return _unitOfWork.SaveChangesEntity();
        }

        public bool DelMaterial(long mid)
        {
            var mobj = _materialRepository.QueryEntityById(mid);

            if (mobj != null)
            {
                _materialRepository.DelEntity(mobj);
                var mpobj = _materialPackageRepository.QueryEntityWhere(x => x.MaterialId == mobj.Id);
                if (mpobj != null)
                    _materialPackageRepository.DelEntity(mpobj);
            }
            return _unitOfWork.SaveChangesEntity();
        }

        public List<Material> GetAllMaterialList()
        {
            var list = _materialRepository.GetEntityAlls();
            return list.ToList();
        }

        public Material? GetMaterialById(long mid)
        {
            var materobj = _materialRepository.QueryEntityById(mid);
            if (materobj != null && materobj.IsDismantle == true)
            {
                var materpackobj = _materialPackageRepository.QueryEntityWhere(x => x.MaterialId == mid);
                if (materpackobj != null)
                {
                    materobj.ConversionFactor = materpackobj.ConversionFactor;
                    if (materpackobj.SubPackageUnitId == null)
                        return null;
                    var iobjs = _itemRepository.QueryEntityById((long)materpackobj.SubPackageUnitId);
                    if (iobjs == null)
                        return null;
                    else
                        materobj.SubPackageUnitId = iobjs.Id;
                }               
                else
                    materobj.ConversionFactor = 0;

            }
            return materobj;
        }

        public List<Material> GetMaterialList(string? mname,  int materialcategoryid, int pageIndex, int pageSize, out int totalCount)
        {

            var list = _materialRepository.GetEntityAlls();
           
            if (!string.IsNullOrEmpty(mname))
            {
                list = list.Where(x => x.Name.Contains(mname) || x.Code.Contains(mname));
            }

            if (materialcategoryid != 0)
            {
                list = list.Where(x => x.MaterialCategoryId == materialcategoryid);
            }
            var lists = _materialRepository.GetEntityAlls(list, pageIndex, pageSize, out totalCount, x => x.CreateDate, false);
            return lists.ToList();
        }

        public bool UpdMaterial(Material m, out string message)
        {
            message = string.Empty;
            var obj = _materialRepository.QueryIsEntityWhere(x => x.Id != m.Id && x.Code == m.Code);
            if (obj != null)
            {
                message = "物料编码已存在！";
                return false;
            }
            if (m.UnitId == null)
            {
                message = "请选择计量单位！";
                return false;
            }
            var iobj = _itemRepository.QueryEntityById((long)m.UnitId);
            if (iobj == null)
            {
                message = "找不到改计量单位！";
                return false;
            }
            else
                m.UnitName = iobj.ItemName;

            if (m.MaterialCategoryId == null)
            {
                message = "请选择物料分类！";
                return false;
            }
            var mcobj = _materialCategoryRepository.QueryEntityById((long)m.MaterialCategoryId);
            if (mcobj == null)
            {
                message = "找不到改分类！";
                return false;
            }
            else
                m.MaterialCategoryName = mcobj.Name;

            _materialRepository.UpdEntity(m);

            var mpobj = _materialPackageRepository.QueryEntityWhere(x => x.MaterialId == m.Id);
            if (mpobj != null)
                _materialPackageRepository.DelEntity(mpobj);

            if (m.IsDismantle != null && m.IsDismantle == true)
            {
                if (m.SubPackageUnitId == null)
                {
                    message = "请选择子计量单位！";
                    return false;
                }
                var iobjs = _itemRepository.QueryEntityById((long)m.SubPackageUnitId);
                if (iobjs == null)
                {
                    message = "找不到该计量单位！";
                    return false;
                }
                else
                {
                    m.SubPackageUnitName = iobjs.ItemName;
                }
                MaterialPackage materialPackage = new MaterialPackage();
                materialPackage.MaterialId = m.Id;
                materialPackage.MaterialCode = m.Code;
                materialPackage.MaterialName = m.Name;
                materialPackage.ConversionFactor = m.ConversionFactor;
                materialPackage.PackageLevel = 1;
                materialPackage.PackageUnitId = iobj.Id;
                materialPackage.PackageUnitName = iobj.ItemName;
                materialPackage.SubPackageUnitId = m.SubPackageUnitId;
                materialPackage.SubPackageUnitName = m.SubPackageUnitName;
                _materialPackageRepository.AddEntity(materialPackage);
                return _unitOfWork.SaveChangesEntity();
            }

            return _unitOfWork.SaveChangesEntity();
        }
    }
}
